/*
 * AX_man.c
 *
 * Created: 15/06/2014 13:05:34
 *  Author: Phil
 */ 

// tick interval is how how long a time cycle takes in ms
#define tick_interval 8
// bit mapping of ports with user friendly names
#define PWRON_PF1 0
#define MODEM_IS_ON_PF0 1
#define RED_LED_PG3 3
#define GREEN_LED_PG4 4
#define RELAY_PC5 5

#include "AX_man.h"


// to be moved to separate file when working
int init_timers(void);
void pause_time(int pause_ms);
void power_on_modem(void);
void init_ports(void);

void init_ports(void){
	// clear outputs and inputs
	PORTF = 0x00;
	PINF = 0x00;
	PORTG = 0x00;
	PORTC = 0x00;
	// we need to make sure of correct IN/OUT directions
	DDRF |= (1<<PWRON_PF1); // output
	DDRF |= (0<<MODEM_IS_ON_PF0); // input
	DDRG |= (1<<RED_LED_PG3); // output
	DDRG |= (1<<GREEN_LED_PG4);//output
	DDRC |= (1<<RELAY_PC5); // output
}

int init_timers(void){
	// Not going to use ISR for this one
	// disable Interrupts
	TIMSK0 &= (0<<TOIE0);
	// set prescalar to max 0xFF
	TCCR0B = 0x04;
	TCNT0 = 0x00;
	return 1;
}

void pause_time(int pause_ms){
	TCNT0 = 0x00;
	int led_flash = 0, tick_count = 0,target = pause_ms/tick_interval ;
	// set target time and count the overflows
	while (tick_count<target )
	{
		TCCR0B = 0x04;
		// test timer for 250 * 256 cycles
		if (TCNT0 > 0xFA){
			// flag has tripped reset it and increment our tic counter
			tick_count ++;
			led_flash ++;
			TCNT0 = 0;
			if (led_flash > 0x09)
			{
				led_flash = 0x00;
				// toggle state
				PORTG ^= (1<<RED_LED_PG3);
				PORTG ^= (1<<GREEN_LED_PG4);
			}
		}
		
	}
}

void power_on_modem(void){
	// send ON signal, wait 1s, then see if modem is on
	// if PIN61 'ON' is low then power up modem via PIN60 'PWRON' and wait 1s keep trying
	//while ((PINF & (1<<MODEM_IS_ON_PF0)) == 0x00)
	//{
		//pause for 1s
		pause_time(1000);
		// power on modem
		PORTF |= (1<<PWRON_PF1);
		// pause for 1s
		pause_time(1000);
		// remove start impulse
		PORTF &= ~(1<<PWRON_PF1);
		// now pause for 300ms
		pause_time(300);
	//}
	// modem must of answered that it powered up!!!
	// switch RED LED on and relay
	PORTG |= (1<<RED_LED_PG3);
	PORTC |= (1<<RELAY_PC5);
}

int main(void)
{
	// SWITCH on interrupt and serial ports
	init_interrupts();
	init_serial_ports();	
	init_timers();
	init_ports();
	power_on_modem(); 
	int cr_count = 0;
	send_string("AX_MAN",11);// send a boot up string
    while(1)
    {
        // during the string pass we will monitor bytes for known types and catch responses
		// has either port gotten data
		if (UART_FLAGS > 0) {
			if ((UART_FLAGS & (1<< PORT1_HAS_DATA)) == (1<<PORT1_HAS_DATA)){
				// reset the flag
				UART_FLAGS &= (0<< PORT1_HAS_DATA);			
			}
			if ((UART_FLAGS & (1<<PORT0_HAS_DATA))==(1<<PORT0_HAS_DATA)){
				// reset the flag
				UART_FLAGS &= (0<<PORT0_HAS_DATA);
				// if its a CR use it as a response Heartbeat from modem
				if (PORT0_DATA == 0x0d) cr_count ++;// increment a flag, toggle LED every 10th <CR>
				if (cr_count > 9)
				{
					cr_count = 0;
					PORTG ^= (1<<GREEN_LED_PG4);
				}
			}
		}
	}
	return(0);
}